//ts 是一个可选的静态的类型检测的语言



//如何进行类型约束

//仅需要在变量，函数的参数，函数的返回值位置加上：类型   any类型表示任意类型，ts不会做类型的检查
//ts在很多时候可以进行类型推倒

// let name:string;

                                //返回值
function sum(a: number, b: number):number {
   return a+b
}

let unm: number = sum(111,222)


let age;//警告




//源代码和编译结果的差异

//变异结果中没有类型约束的信息




//------------------------>  ts中的数据类型  <----------------------

//基本数据类型
  //string  number boolean   数组 Array  对象Object  null/undefined

  //数字的数组
  let nums:number[];
  nums = [111]
  let numb:Array<number> = [111]; //语法糖

  function isOdd(n:number):boolean {
       return n % 2 === 0;
  }

  let u:object;
  u = {
      age:"13"
  }

 // null/undefined 可以赋值给任意类型



//--------------------------》《=--------------------
 //常用数据类型
   //联合类型 ：将多种类型任选其一，配合类型保护 
         //类型保护：当对某个变量进行类型判断后，在判断语句块中便可以确定她的类型typeof
        let name:string | number;
        name = 'aaaa'
        if(typeof name === 'string') {
            name.includes('11')
        } else {
            console.log(name)
        }
   //void类型： 通常用于约束函数的返回，通常表示函数没有返回,
       function printMenu(): void {
           console.log('1111')
       }
       printMenu()
   //never类型：用于约束函数的返回，表示该函数永远不会结束

       function throwError(msg:string):never {
            throw new Error(msg)
       };
    //字面量类型：使用一个值进行约束
        let a:"A";
        a = 'A'  //赋值时只能是这个

        let sex:"男"|"女";

        let arr:[];  //arr永远只能取值为一个空数组

        let obj:{
            name:string;
            age:number;
        }
        obj = {  //ob必须有这两个属性，并且这两个属性的类型必须合法
            name:'aqiang',
            age:60
        }
    //元祖类型：表示一个固定长度的数组，并且数组中每一项的类型确定
       let tu:[string, number];  //数组必须有两项，并且第一个是string ,第二项是number


    //any类型：any类型可以绕过类型检测，因此any类型的数据可以赋值给任意类型
       let data:any;
       data = []
       data = {}
       data = '111'

// -------------------------->类型别名<------------------
//类型别名:对已知的一些类型定义名称 
    type Sex = "男" | "女"
    type User = {
        name:string;
        age:number;
        sex:Sex
    }
    

    let q : User;
    q = {
        name:'qqq',
        age:19,
        sex:"男"
    }

    function getUsers(g:Sex):User[] {
       return[]
    }

    //---------------------->函数的相关约束<------------------
      //函数重载，在函数实现之前，对函数调用的多种情况进行声明



      /**
       * 得到 a * b的结果
       * @param a 
       * @param b 
       */
      function combine(a:number, b:number):number;   

      /**
       * 得到a拼接b的结果
       * @param a 
       * @param b 
       */
      function combine(a:string, b:string):string;
      function combine(a:number|string, b:number|string) : number|string {
          if(typeof a === 'number' && typeof b === 'number') {
              return a * b
          } else if(typeof a === 'string' && typeof b === 'string') {
            return a + b
          }
          throw new Error('a 和 b必须是相同的类型');
          
      }
    
      let result = combine(3,3)
      //let result = combine('qqq','ssss')



      //可选参数：可以在某些参数后面加上问好，表示该参数是可以不用传递的

      function sumA(a:number, b:number, c?:number):number {
         if(c) {
            return a + b +c
         } else {
            return a + b
         }
      }

      sumA(1,3)
      sumA(1,3,4)
       //默认参数
       function add(a:number, b:number, c:number = 0):number {
           return a + b +c
      }
      add(1, 2)
      add(1,3,4)